<?php
final class DB {
	private $pdo = null;
	private $statement = null;
	
	
	//这里的driver暂时占位，为了兼容性。以后要删除的
	public function __construct($driver ,$hostname, $username, $password, $database, $port = '3306') {
		try {
			//创建pdo持久连接
			$this->pdo = new \PDO("mysql:host={$hostname};port={$port};dbname={$database}", $username, $password, array(\PDO::ATTR_PERSISTENT => true));
		} catch(\PDOException $e) {
			trigger_error('Error: Could not make a database link ( ' . $e->getMessage() . '). Error Code : ' . $e->getCode() . ' <br />');
			exit();
		}
		$this->pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);//禁用pdo模拟预处理语句
		
		$this->pdo->exec('SET NAMES \'utf8\'');
		$this->pdo->exec('SET CHARACTER SET utf8');
		$this->pdo->exec('SET CHARACTER_SET_CONNECTION=utf8');
		$this->pdo->exec('SET SQL_MODE = \'\'');

	}

	public function prepare($sql) {
		$this->statement = $this->pdo->prepare($sql);
	}

	public function bindParam($parameter, $variable, $data_type = \PDO::PARAM_STR, $length = 0) {
		if ($length) {
			$this->statement->bindParam($parameter, $variable, $data_type, $length);
		} else {
			$this->statement->bindParam($parameter, $variable, $data_type);
		}
	}

	public function execute() {
		try {
			if ($this->statement && $this->statement->execute()) {
				/*$data = array();

				while ($row = $this->statement->fetch(\PDO::FETCH_ASSOC)) {
					$data[] = $row;
				}*/
				$data = $this->statement->fetchAll(\PDO::FETCH_ASSOC);

				$result = new \stdClass();
				$result->row = (isset($data[0])) ? $data[0] : array();
				$result->rows = $data;
				$result->num_rows = $this->statement->rowCount();
			}
		} catch(\PDOException $e) {
			trigger_error('Error: ' . $e->getMessage() . ' Error Code : ' . $e->getCode());
		}
	}

	public function query($sql, $params = null) {
		$result = false;

		try {
			if(empty($params)){
				//如果参数为空，则执行普通的query
				$this->statement = $this->pdo->query($sql);
				if($this->statement){
					$data = $this->statement->fetchAll(\PDO::FETCH_ASSOC);

					$result = new \stdClass();
					$result->row = (isset($data[0]) ? $data[0] : array());//返回查询结果第一行
					$result->rows = $data;//返回所有查询结果
					$result->num_rows = $this->statement->rowCount();//返回查询结果行数
				}
			}else{
				//如果参数不为空，则执行prepare
				$this->statement = $this->pdo->prepare($sql);
				if ($this->statement && $this->statement->execute($params)) {
					$data = $this->statement->fetchAll(\PDO::FETCH_ASSOC);

					$result = new \stdClass();
					$result->row = (isset($data[0]) ? $data[0] : array());//返回查询结果第一行
					$result->rows = $data;//返回所有查询结果
					$result->num_rows = $this->statement->rowCount();//返回查询结果行数
				}
			}
		} catch (\PDOException $e) {
			trigger_error('Error: ' . $e->getMessage() . ' Error Code : ' . $e->getCode() . ' <br />' . $sql.'<br/>');
			exit();
		}

		if ($result) {
			return $result;
		} else {
			$result = new \stdClass();
			$result->row = array();
			$result->rows = array();
			$result->num_rows = 0;
			return $result;
		}
	}
	
	//数据库过滤
	public function escape($value) {
		return str_replace(array("\\", "\0", "\n", "\r", "\x1a", "'", '"'), array("\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"'), $value);
	}
	
	//数据库语句执行影响行数
	public function countAffected() {
		if ($this->statement) {
			return $this->statement->rowCount();
		} else {
			return 0;
		}
	}
	
	//获取最后的主键id
	public function getLastId() {
		return $this->pdo->lastInsertId();
	}
	
	
	//启动一个事务
	public function beginTransaction(){
		return $this->pdo->beginTransaction();
	}
	//检测是否在一个事务内
	public function inTransaction(){
		return $this->pdo->inTransaction();
	}
	//事务回滚
	public function rollBack(){
		return $this->pdo->rollBack();
	}
	//提交事务
	public function commit(){
		return $this->pdo->commit();
	}


	//简易的插入
	public function insert($table,$parameters){
		if(is_string($table) && is_array($parameters) && !empty($parameters)){
			$sql = "INSERT INTO `{$table}` SET ";
			$params = array();
			$isFirst = true;//是否第一次的循环，这个是为了判断拼接的字符串是否需要加逗号
			foreach($parameters as $key=>$value){
				//如果是使用日期函数的，那么直接拼接
				if($isFirst === false){
					if($value === 'NOW()'){
						$sql .= " ,`{$key}`=NOW()";
					}else{
						$sql .= " ,`{$key}`=:{$key}";
						$params[":{$key}"]=$value;
					}
				}else{
					$isFirst = false;
					if($value === 'NOW()'){
						$sql .= "`{$key}`=NOW()";
					}else{
						$sql .= "`{$key}`=:{$key}";
						$params[":{$key}"]=$value;
					}
				}
			}
			$this->query($sql,$params);
			if($this->countAffected()>0){
				return true;
			}else{
				return false;
			}
		}else{
			return false;
		}
	}
	
	public function __destruct() {
		$this->pdo = null;
	}
}